package Demo1

import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}

/**
  * Created by lenovo on 2017/9/25.
  * 连接mysql
  */
object SparkSQLTest1 {

  def main(args: Array[String]) {
    System.setProperty("hadoop.home.dir","E://hadoop-liyadong//hadoop-2.7.1")

    val conf = new SparkConf().setAppName("SparkSQLTest1").setMaster("local[2]").set("spark.testing.memory","2147480000")
    val sc = new SparkContext(conf)
    val sparkSQL = new SQLContext(sc)

    val url = "jdbc:mysql://localhost:3306/hive"
    val jdbcDF = sparkSQL.read.format("jdbc").options(
      Map("url" -> url,
          "user" -> "root",
          "password" -> "root",
          "dbtable" -> "fieldstable")).load()
    //打印出查询的表的内容
    jdbcDF.show()
    //打印出获取指定字段的统计信息
    jdbcDF.describe("order_id","fields").show()

    /**
      * 1、where条件相关
    （1）where(conditionExpr: String)：SQL语言中where关键字后的条件
　　传入筛选条件表达式，可以用and和or。得到DataFrame类型的返回结果，
      */
    jdbcDF.where("order_id=5 or fields='empno'").show()

    /**
      * （2）filter：根据字段进行筛选
　　传入筛选条件表达式，得到DataFrame类型的返回结果。和where使用条件相同
      */
    jdbcDF.filter("order_id=5 or fields='empno'").show()

    /**
      * 2、查询指定字段
    （1）select：获取指定字段值
　　根据传入的String类型字段名，获取指定字段的值，以DataFrame类型返回
      */
    jdbcDF.select("order_id","fields").show()

    /**
      * 还有一个重载的select方法，不是传入String类型参数，而是传入Column类型参数。可以实现select id, id+1 from test这种逻辑。
      */
    jdbcDF.select(jdbcDF("order_id"),jdbcDF("order_id")+1).show()

    /**
      * （2）selectExpr：可以对指定字段进行特殊处理
　　可以直接对指定字段调用UDF函数，或者指定别名等。传入String类型参数，得到DataFrame对象。
　　示例，查询id字段，c3字段取别名time，c4字段四舍五入：
      */
    jdbcDF.selectExpr("order_id as id","round(order_id)").show(false)

    val id = jdbcDF.col("order_id")
    println("*"+id)

    val id1 = jdbcDF.apply("fields")
    println("&"+id1)

    val id2 = jdbcDF("order_id")
    println("%"+id2)

    /**
      * （5）drop：去除指定字段，保留其他字段
　　返回一个新的DataFrame对象，其中不包含去除的字段，一次只能去除一个字段。
      */
    jdbcDF.drop("order_id").show()

    /**
      * 3、limit
　　limit方法获取指定DataFrame的前n行记录，得到一个新的DataFrame对象。和take与head不同的是，
    limit方法不是Action操作。
      */
    jdbcDF.limit(2).show()

    /**
      * 4、order by
  （1）orderBy和sort：按指定字段排序，默认为升序
　　示例1，按指定字段排序。加个-表示降序排序。sort和orderBy使用方法相同
    jdbcDF.orderBy(- jdbcDF("c4")).show(false)
    / / 或者
    jdbcDF.orderBy(jdbcDF("c4").desc).show(false)
      */
    jdbcDF.orderBy(- jdbcDF("order_id")).show()
    jdbcDF.orderBy(jdbcDF("order_id")).show()
    jdbcDF.sort(jdbcDF("order_id").desc).show()
    println("*********************************************************")

    /**
      * （2）sortWithinPartitions
　　和上面的sort方法功能类似，区别在于sortWithinPartitions方法返回的是按Partition排好序的DataFrame对象。
      */
    jdbcDF.sortWithinPartitions("order_id").show()

    /**
      * 5、group by
  （1）groupBy：根据字段进行group by操作
　　groupBy方法有两种调用方式，可以传入String类型的字段名，也可传入Column类型的对象。
      */
    jdbcDF.groupBy("order_id")
  }
}
